#include "spi.h"
#include "stm32f4xx_spi.h"

#define SPI_BAUDRATE_650KHZ   SPI_BaudRatePrescaler_64
#define SPI_BAUDRATE_4kHZ   SPI_BaudRatePrescaler_128

#define SPI_CLK					RCC_APB1Periph_SPI2
#define SPI_CLK_INIT			RCC_APB1PeriphClockCmd
#define SPI_IRQ_HANDLER			SPI2_IRQHandler
#define SPI_IRQn				SPI2_IRQn

#define SPI2_SCK_PIN           	GPIO_Pin_13
#define SPI2_MISO_PIN			GPIO_Pin_14
#define SPI2_MOSI_PIN			GPIO_Pin_15

#define SPI3_SCK_PIN           	GPIO_Pin_3
#define SPI3_MISO_PIN			GPIO_Pin_4
#define SPI3_MOSI_PIN			GPIO_Pin_5

#define SPI_CS_MPU6500_PIN      GPIO_Pin_8
#define SPI_CS_PMW_PIN      	GPIO_Pin_9

/**
 * @Description SPI3初始化400khz、用于与MPU6500通信
 */
void SPI3_to_MPU6500_Init(void)
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
	
	/* SCK=PB3, MISO=PB4 MOSI=PB5*/
	GPIO_InitStructure.GPIO_Pin = SPI3_SCK_PIN | SPI3_MISO_PIN | SPI3_MOSI_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOB,SPI3_SCK_PIN,GPIO_AF_SPI3);
	GPIO_PinAFConfig(GPIOB,SPI3_MISO_PIN,GPIO_AF_SPI3);
	GPIO_PinAFConfig(GPIOB,SPI3_MOSI_PIN,GPIO_AF_SPI3);
	
	//PC8=MPU6500_CS PC9=LSM303_CS
	GPIO_SetBits(GPIOC, SPI_CS_MPU6500_PIN | SPI_CS_PMW_PIN);
	GPIO_InitStructure.GPIO_Pin = SPI_CS_MPU6500_PIN | SPI_CS_PMW_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	/* SPI3 configuration  */
	SPI_Cmd(SPI3, DISABLE);        
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //SPI全双工通信
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;      					//主机模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;     				//8个数据位
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;       					//空闲极性为低
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    					//第一个下降沿采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;      						//软件控制NSS
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BAUDRATE_650KHZ; 		//spi波特率 = 42Mhz / 64 = 2/3mhz = 650khz = 1.5US
	
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;     				//高位在前
	SPI_InitStructure.SPI_CRCPolynomial = 7;       						//crc校验
    
	SPI_Init(SPI3, &SPI_InitStructure);	 
	SPI_Cmd(SPI3, ENABLE);
}


/**
 * @Description SPI2 初始化 与光流模块PMW3901通信
 */
void SPI2_to_PMW_Init(void)  
{
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef  SPI_InitStructure;

	/* 使能GPIO时钟 */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

	/* 使能SPI时钟 */
	SPI_CLK_INIT(SPI_CLK, ENABLE);

	/*复用功能设置 */
	GPIO_PinAFConfig(GPIOB, SPI2_SCK_PIN, GPIO_AF_SPI2);
	GPIO_PinAFConfig(GPIOB, SPI2_MISO_PIN, GPIO_AF_SPI2);
	GPIO_PinAFConfig(GPIOB, SPI2_MOSI_PIN, GPIO_AF_SPI2);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

	GPIO_InitStructure.GPIO_Pin = SPI2_SCK_PIN | SPI2_MOSI_PIN | SPI2_MISO_PIN;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/*!< SPI 参数配置 */
	SPI_I2S_DeInit(SPI2);
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	//全双工
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BAUDRATE_4kHZ;		//波特率=42/32 = 2Mhz
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 0; 							//无需要CRC

	SPI_Init(SPI2, &SPI_InitStructure);
	SPI_Cmd(SPI2, ENABLE);
}


/**
 * @Description spi2 交换数据
 */
bool SPI2_PMW_Exchange(uint32_t length, const uint8_t * data_tx, uint8_t * data_rx)
{

	uint8_t i=0,retry=0;
	
	//循环一个个字节发送、读取
	for(i=0;i<length;i++){
		//等待发送完成
		while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET){
			retry++;
			if(retry>200){
				return false;		
			}
		}
		SPI_I2S_SendData(SPI2,data_tx[i]);
		retry=0;
		//等待接收完成
		while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET){
			retry++;
			if(retry>200){
				return false;		
			}		
		}
		retry=0;
		//读取接收区的数据
		data_rx[i] = SPI_I2S_ReceiveData(SPI2);
	}
	
	return true;
}


/**
 * @Description spi3 交换一个字节数据
 */
uint8_t SPI3_ReadWrite_Byte(uint8_t byte)
{
	//等待发送完成、写入新的数据、返回接收的一个字节数据
	while((SPI3->SR & SPI_I2S_FLAG_TXE)==RESET);
	SPI3->DR = byte;  
	
	while((SPI3->SR & SPI_I2S_FLAG_RXNE)==RESET);
	return(SPI3->DR);
}

/**
 * @Description spi3 写一个寄存器
 */
void SPI3_WriteReg(u8 reg ,u8 data){
	
	SPI3_ReadWrite_Byte(reg);
	SPI3_ReadWrite_Byte(data);
}

/**
 * @Description spi3 读一个寄存器
 */
u8 SPI3_ReadReg(u8 reg){
	SPI3_ReadWrite_Byte(reg|0x80);
	return SPI3_ReadWrite_Byte(0xff);
}

/**
 * @Description spi3 读取多个寄存器
 */
void SPI3_ReadRegs(u8 reg, u8 length, u8 *data){
	u8 count = 0;
	SPI3_ReadWrite_Byte(reg|0x80);
	for(count=0;count<length;count++){
		data[count] = SPI3_ReadWrite_Byte(0xff);
	}
}

